package game.Actors;

import java.util.ArrayList;

import game.LevelManager;
import game.Config.Config;

import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Vector2f;
import org.newdawn.slick.tiled.TiledMap;
/**
 * This class represents a bullet fired from another actor.
 * Bullet extends MovableActor, and therefore moves
 * through the screen when updated. A bullet
 * is given a direction and speed when created
 * and moves according to these while still on-screen.
 * If a bullet encounters an enemy, the bullet will hit
 * the enemy and inflict damage.
 * @author Sebastian Isheden and Victor Beer
 *
 */
public  class Bullet extends MovableActor{
	protected float damage;
	/**
	 * Constructor for Bullet. Creates a bullet with given
	 * parameters.
	 * @param image The image of the bullet.
	 * @param speed The speed of the bullet.
	 * @param damage The damage of the bullet.
	 * @param direction The direction of the bullet.
	 * @param position The starting position of the bullet.
	 */
    public Bullet(Image image, Vector2f position, float speed, Vector2f direction, float damage) {
		super(image, position, speed, direction);
		this.damage = damage;
	}

    @Override
	protected void update(int delta){
    	super.update(delta);
    	if(this.isOnImpassable()){
    		this.blow();
    	}
        checkEnemyCollision();
	}
    protected void checkEnemyCollision() {
    	ArrayList<Enemy> enemies = Enemy.getEnemyList();
    	for(int i = enemies.size() - 1; i >= 0; i--) {
    		if(isColliding(enemies.get(i))) {
    			enemies.get(i).hit(this.damage);
    			this.explode(enemies.get(i));
    		}
    	}
		
	}

	//Blows up the bullet.
    protected void blow() {
		this.isDead = true;
		
	}

	private boolean isOnImpassable() {
		TiledMap map = LevelManager.getCurrentLevel().getTileMap();
		Vector2f tilePosition = this.position.copy().scale(1/Config.TILE_PIXEL_AMOUNT);
		if(tilePosition.x <= 0 || tilePosition.x >= map.getWidth()) {
			return true;
		}
		if(tilePosition.y <= 0 || tilePosition.y >= map.getHeight()) {
			return true;
		}
		if(map.getTileId((int)tilePosition.x, (int)tilePosition.y, Config.COLLISION_LAYER_ID) == Config.IMPASSABLE_TILE_ID){
			return true;
		}
		return false;
	}

	protected void explode(Enemy enemy) {
    	this.isDead = true;
    }
    
    protected boolean isColliding(Enemy enemy) {
    	if(this.position.copy().add(new Vector2f(-enemy.position.x, -enemy.position.y)).length() < 
    	   this.image.getWidth()/2 + Config.ENEMY_COLLISION_RANGE) {
    		return true;
    	}
    	return false;
    }

	

}
